﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EditorGame;
using Microsoft.Xna.Framework;
using System.Reflection;
using Microsoft.Xna.Framework.Graphics;
using System.Diagnostics;

namespace EditorForm
{
    public partial class EditorForm : Form
    {
        private Game1 game;

        public EditorForm()
        {
            InitializeComponent();

            // create the game
            game = new Game1();
            game.IsMouseVisible = true;

            // force the game to run in a window
            IGraphicsDeviceManager graphicsDeviceManager =
                (IGraphicsDeviceManager)game.Services.GetService(typeof(IGraphicsDeviceManager));
            graphicsDeviceManager.CreateDevice();

            // beginDraw() relies on this
            game.GetType().BaseType.GetField("graphicsDeviceManager",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(game, graphicsDeviceManager);

            // embed the render window into this form
            Form form = game.Form;
            form.FormBorderStyle = FormBorderStyle.None;
            form.Dock = DockStyle.Fill;
            form.TopLevel = false;
            form.Parent = this;
            form.Visible = true;
            Controls.Add(form);

            // handle resize event for render window
            game.Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged);

            // handle Application events
            System.Windows.Forms.Application.Idle += new EventHandler(Application_Idle);

            // NOTE: you could create components here...

            // call Initialize and BeginRun
            game.GetType().BaseType.GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(game, null);
            game.GetType().BaseType.GetMethod("BeginRun", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(game, null);

            // get the gametime and call the first update
            GameTime gt = game.GetType().BaseType.GetField("gameTime",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(game) as GameTime;
            game.GetType().BaseType.GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(game, new Object[] { gt });

            // set doneFirstUpdate to true
            game.GetType().BaseType.GetField("doneFirstUpdate",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(game, true);

            ParticleEditorControls particleEditorControls = new ParticleEditorControls(game.Emitter);
            particleEditorControls.Visible = true;

            // set up listBox1
            /*Texture2D texture = game.Content.Load<Texture2D>(@"particle/circle");
            game.Textures.Add("circle", texture);
            texture = game.Content.Load<Texture2D>(@"particle/star");
            game.Textures.Add("star", texture);
            texture = game.Content.Load<Texture2D>(@"particle/diamond");
            game.Textures.Add("diamond", texture);
            texture = game.Content.Load<Texture2D>(@"particle/circle_gradient");
            game.Textures.Add("circle_gradient", texture);
            listBox1.Items.Add("circle");
            listBox1.Items.Add("star");
            listBox1.Items.Add("diamond");
            listBox1.Items.Add("circle_gradient");
            listBox1.SelectedIndex = 0;
            */
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);

            System.Windows.Forms.Application.Idle -= Application_Idle;
        }

        void Application_Idle(object sender, EventArgs e)
        {
            while (AppStillIdle())
                game.Tick();
        }

        private bool AppStillIdle()
        {
            NativeMethods.Message msg;
            return !(NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0));
        }

        void Window_ClientSizeChanged(object sender, EventArgs e)
        {
            GameWindow window = game.Window;
            if (game.Window.ClientBounds.Width != 0 && game.Window.ClientBounds.Height != 0)
                game.SetAspectRatio(game.Window.ClientBounds);
        }

        /*private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            game.Emitter.EmitterData.ParticleCount = (int)numericUpDown1.Value;
            game.Emitter.UpdateParticleCount();
        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            game.Emitter.EmitterData.ParticleMaxSpawnCount = (int)numericUpDown2.Value;
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            game.Emitter.EmitterData.Texture = game.Textures[(string)listBox1.SelectedItem];
            game.Emitter.UpdateParticleData();
        }*/
    }
}
